package com.mengshuai.technology.common.db.mysql;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
@Slf4j
public class DataSourceAspect {

    /**
     * 匹配所有 Mapper 接口方法
     */
    @Pointcut("execution(* com.mengshuai.technology..mapper.*.*(..))")
    public void dataSourcePointCut() {
    }

    @Around("dataSourcePointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        try {
            // 获取方法名
            MethodSignature signature = (MethodSignature) point.getSignature();
            Method method = signature.getMethod();
            // 如果有 @TargetDataSource 注解，优先使用注解的数据源
            if (method.isAnnotationPresent(TargetDataSource.class)) {
                TargetDataSource annotation = method.getAnnotation(TargetDataSource.class);
                String dbType = annotation.value();
                DataSourceContextHolder.setDataSourceType(dbType);
                log.info("使用注解指定的数据源：" + dbType);
                return point.proceed();
            }
            // 否则通过 SQL 类型判断
            String methodName = method.getName();
            if (methodName.startsWith("select") ||
                    methodName.startsWith("get") ||
                    methodName.startsWith("query") ||
                    methodName.startsWith("find") ||
                    methodName.startsWith("list") ||
                    methodName.startsWith("count")) {
                DataSourceContextHolder.setDataSourceType("slave1");
                log.info("自动切换到从库：slave1");
            } else {
                DataSourceContextHolder.setDataSourceType("master");
                log.info("自动切换到主库：master");
            }

            return point.proceed();
        } finally {
            DataSourceContextHolder.clearDataSourceType(); // 清理线程变量
        }
    }
}
